!------------------------------------------------------------------------------
! TJU/Department of Mechanics, Fluid Mechanics, Code START
!------------------------------------------------------------------------------
!> @Author: Jianxin Liu shookware@tju.edu.cn
!> @Date: 2024-08-27 10:31:25
!> @LastEditTime: 2024-08-27 15:01:38
!> @LastEditors: Jianxin Liu shookware@tju.edu.cn
!> @Description: 
!> @FilePath: /START_NS_3D/src/third_party/field/src/module_transformer.f90
!> @Copyright (c) 2024 by Jianxin Liu email: shookware@tju.edu.cn, All Rights Reserved.
!------------------------------------------------------------------------------
module mod_transformer

   use mod_conservative
   use mod_primitive
   use mod_conservative_multispecies
   use mod_primitive_multispecies
   use petsc_wrapper
   use iso_fortran_env, only: dp => real64

   interface transform_field_c2p
      module procedure :: transform_conervative_to_primitive_normal
      module procedure :: transfrom_conservative_to_primitive_multispecies
   end interface
   interface transform_field_p2c
      module procedure :: transform_primitive_to_conservative_normal
      module procedure :: transfrom_primitive_to_conservative_multispecies
   end interface

   interface global_to_local
      module procedure :: global_to_local_conservative
      module procedure :: global_to_local_primitive
      module procedure :: global_to_local_conservative_multispecies
      module procedure :: global_to_local_primitive_multispecies
   end interface

contains

   subroutine transform_conervative_to_primitive_normal(conservative, primitive)
      implicit none
      type(type_conservative), intent(in) :: conservative
      type(type_primitive), intent(inout) :: primitive
      real(dp), pointer :: q(:)
      real(dp), pointer :: rho(:), u(:), v(:), w(:), T(:)

      integer :: l
      real(dp) ::  para, cv

      call conservative%q%get_array_read(q)
      call primitive%rho%get_array(rho)
      call primitive%u%get_array(u)
      call primitive%v%get_array(v)
      call primitive%w%get_array(w)
      call primitive%T%get_array(T)

      para = 1.0d0/((conservative%eos%ref%flg_uref)**2/conservative%eos%ref%gamma)

      do l = 1, size(rho)
         rho(l) = q((l - 1)*5 + 1)
         u(l) = q((l - 1)*5 + 2)/rho(l)
         v(l) = q((l - 1)*5 + 3)/rho(l)
         w(l) = q((l - 1)*5 + 4)/rho(l)
         cv = conservative%eos%gas%get_cv()/conservative%eos%ref%R
         T(l) = (q((l - 1)*5 + 5)/rho(l) - 0.5_dp*(u(l)**2 + v(l)**2 + w(l)**2))/cv*para
      end do

      call conservative%q%restore_array_read(q)
      call primitive%rho%restore_array(rho)
      call primitive%u%restore_array(u)
      call primitive%v%restore_array(v)
      call primitive%w%restore_array(w)
      call primitive%T%restore_array(T)

   end subroutine transform_conervative_to_primitive_normal

   subroutine transform_primitive_to_conservative_normal(primitive, conservative)
      implicit none
      type(type_primitive), intent(in) :: primitive
      type(type_conservative), intent(inout) :: conservative
      real(dp), pointer :: q(:)
      real(dp), pointer :: rho(:), u(:), v(:), w(:), T(:)

      integer :: l
      real(dp) :: para, cv

      call primitive%rho%get_array_read(rho)
      call primitive%u%get_array_read(u)
      call primitive%v%get_array_read(v)
      call primitive%w%get_array_read(w)
      call primitive%T%get_array_read(T)

      call conservative%q%get_array(q)

      para = (conservative%eos%ref%flg_uref)**2/conservative%eos%ref%gamma
      do l = 1, size(rho)
         q((l - 1)*5 + 1) = rho(l)
         q((l - 1)*5 + 2) = rho(l)*u(l)
         q((l - 1)*5 + 3) = rho(l)*v(l)
         q((l - 1)*5 + 4) = rho(l)*w(l)
         cv = primitive%eos%gas%get_cv()/primitive%eos%ref%r
         q((l - 1)*5 + 5) = rho(l)*(cv*T(l)*para + 0.5_dp*(u(l)**2 + v(l)**2 + w(l)**2))
      end do

      call primitive%rho%restore_array_read(rho)
      call primitive%u%restore_array_read(u)
      call primitive%v%restore_array_read(v)
      call primitive%w%restore_array_read(w)
      call primitive%T%restore_array_read(T)
      call conservative%q%restore_array(q)

   end subroutine transform_primitive_to_conservative_normal

   subroutine transfrom_conservative_to_primitive_multispecies(conservative, primitive)
      type(type_conservative_multispecies), intent(in) :: conservative
      type(type_primitive_multispecies), intent(inout) :: primitive

   end subroutine transfrom_conservative_to_primitive_multispecies

   subroutine transfrom_primitive_to_conservative_multispecies(primitive, conservative)
      type(type_primitive_multispecies), intent(in) :: primitive
      type(type_conservative_multispecies), intent(inout) :: conservative

   end subroutine transfrom_primitive_to_conservative_multispecies

   subroutine global_to_local_primitive(primitive_global, primitive_local)
      class(type_primitive), intent(in) :: primitive_global
      class(type_primitive), intent(inout) :: primitive_local

      call domain_global_vector_to_local(primitive_global%rho, primitive_local%rho)
      call domain_global_vector_to_local(primitive_global%u, primitive_local%u)
      call domain_global_vector_to_local(primitive_global%v, primitive_local%v)
      call domain_global_vector_to_local(primitive_global%w, primitive_local%w)
      call domain_global_vector_to_local(primitive_global%T, primitive_local%T)

   end subroutine global_to_local_primitive

   subroutine global_to_local_primitive_multispecies(primitive_global, primitive_local)
      class(type_primitive_multispecies), intent(in) :: primitive_global
      class(type_primitive_multispecies), intent(inout) :: primitive_local

      call domain_global_vector_to_local(primitive_global%rho, primitive_local%rho)
      call domain_global_vector_to_local(primitive_global%u, primitive_local%u)
      call domain_global_vector_to_local(primitive_global%v, primitive_local%v)
      call domain_global_vector_to_local(primitive_global%w, primitive_local%w)
      call domain_global_vector_to_local(primitive_global%T, primitive_local%T)

   end subroutine global_to_local_primitive_multispecies

   subroutine global_to_local_conservative(conservative_global, conservative_local)
      class(type_conservative), intent(in) :: conservative_global
      class(type_conservative), intent(inout) :: conservative_local

      call domain_global_vector_to_local(conservative_global%Q, conservative_local%Q)

   end subroutine global_to_local_conservative

   subroutine global_to_local_conservative_multispecies(conservative_global, conservative_local)
      class(type_conservative_multispecies), intent(in) :: conservative_global
      class(type_conservative_multispecies), intent(inout) :: conservative_local

      call domain_global_vector_to_local(conservative_global%Q, conservative_local%Q)

   end subroutine global_to_local_conservative_multispecies

end module mod_transformer
